package cn.krund.lyc.hotlerobot.utils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * @包名: cn.krund.lyc.hotlerobot.utils
 * @作者: 刘育成
 * @时间: 2018/4/5  15:11
 * @org: 克路德人工智能
 * @描述: TODO
 * @fileName: HttpRequest
 */

public class HttpRequest {
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url;
            if (param != null && param != "") {
                urlNameString += "?" + param;
            }
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("app", "true");
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            //如果连接公司服务端失败，则用百度的GPS定位获得城市
            result = locationCityByIp();
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        if (result == null) {
            result = locationCityByIp();
        }
        return result;
    }

    /**
     * 获取到地图图片的信息
     *
     * @param url
     * @param userId
     * @param robotTypeId
     * @return
     */
    public static String sendHttpGetMapImg(String url, String userId, String robotTypeId, String robotId) {
        String result = "";
        BufferedReader in = null;
        try {
            String params = "userId=" + userId + "&robotTypeId=" + robotTypeId + "&robotId=" + robotId;
            String urlNameString = url + "?" + params;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("app", "true");
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("app", "true");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }


    public static String sendHttpPost(String url, Map<String, String> map) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            JSONObject jsonObject = new JSONObject(map);
            String postJson = jsonObject.toString();
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("app", "true");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
//            out = new O PrintWriter(conn.getOutputStream());
//            // 发送请求参数,以JSON串的方式发送
//            out.print(postJson);

            out = new OutputStreamWriter(conn.getOutputStream(), "8859_1");
            out.write(postJson); // 向页面传递数据。post的关键所在！
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String postStream(String str_url, Map<String, String> map) {
        try {
            String pathUrl = str_url;
            //建立连接
            URL url = new URL(pathUrl);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

            ////设置连接属性
            httpConn.setDoOutput(true);//使用 URL 连接进行输出
            httpConn.setDoInput(true);//使用 URL 连接进行输入
            httpConn.setUseCaches(false);//忽略缓存
            httpConn.setRequestMethod("POST");//设置URL请求方法
            httpConn.setConnectTimeout(5000);
            httpConn.setReadTimeout(10000);
            //String requestString = "客服端要以以流方式发送到服务端的数据...";

            JSONObject jsonObject = new JSONObject(map);
            String postJson = jsonObject.toString();

            //设置请求属性
            //获得数据字节数据，请求数据流的编码，必须和下面服务器端处理请求流的编码一致
            byte[] requestStringBytes = postJson.getBytes("utf-8");
            httpConn.setRequestProperty("app", "true");
            httpConn.setRequestProperty("Content-length", "" + requestStringBytes.length);
            httpConn.setRequestProperty("Content-Type", "application/octet-stream");
            httpConn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
            httpConn.setRequestProperty("Charset", "UTF-8");
            //
            String name = URLEncoder.encode("kelude", "utf-8");
//            httpConn.setRequestProperty("", data);
            for (Map.Entry<String, String> entry : map.entrySet()) {
                httpConn.setRequestProperty(entry.getKey(), entry.getValue());
            }

            //建立输出流，并写入数据
            OutputStream outputStream = httpConn.getOutputStream();
            outputStream.write(requestStringBytes);
            outputStream.close();
            //获得响应状态
            int responseCode = httpConn.getResponseCode();
            if (HttpURLConnection.HTTP_OK == responseCode) {//连接成功

                //当正确响应时处理数据
                StringBuffer sb = new StringBuffer();
                String readLine;
                BufferedReader responseReader;
                //处理响应流，必须与服务器响应流输出的编码一致
                responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "utf-8"));
                while ((readLine = responseReader.readLine()) != null) {
                    sb.append(readLine).append("\n");
                }
                responseReader.close();
                return sb.toString();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return "";
    }


    public static String getWeather() {
        String localCity = CityAddress();//获得当前城市名称
        String city = localCity.substring(0, (localCity.length() - 1));
        String cityId = HttpRequest.cityCode(city); //获得城市对应的id
        String weatherInfo = HttpRequest.getWeatherInfo(localCity, cityId);//获得天气情况
        // String weatherInfo = HttpRequest.getWeatherInfo("北京", "101010100");//获得天气情况
        if (weatherInfo != null) {
            return weatherInfo;
        }
        return null;
    }

    /**
     * 通过ip定位当前所在城市，
     * BankStandbyActivity(银行待机界面)上获得机器人所在城市，便于获得当前城市的天气
     *
     * @return 城市名称
     */
    private static String locationCityByIp() {
        String httpUrl = "http://api.map.baidu.com/location/ip";
        BufferedReader reader = null;
        String city = null;
        StringBuffer sbf = new StringBuffer();
        httpUrl = httpUrl + "?" + "ak=3sxaoiZeEFDi6DNXhekeXdIw";
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.connect();
            InputStream is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            String result = sbf.toString();
            JSONObject object = new JSONObject(decodeUnicode(result));
            JSONObject content = object.getJSONObject("content");
            JSONObject address_detail = content.getJSONObject("address_detail");
            city = address_detail.getString("city").replace("市", "");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return city;
    }

    /**
     * 获取当前所在城市，
     * BankStandbyActivity(银行待机界面)上获得机器人所在城市，便于获得当前城市的天气
     *
     * @return 城市名称
     */
    public static String CityAddress() {
        String cityAddress = "北京市";//默认值
        String urlString = Constant.CITYADDRESS;
        for (int i = 0; i < 5; i++) {
            cityAddress = sendGet(urlString, null);
            if (!cityAddress.equals("")) {
                return cityAddress;
            }
        }

        return cityAddress;
    }


    /**
     * 获取城市id
     * 根据locationCityByIp方法获得城市，来获得城市对应的id
     *
     * @param cityName 城市名称
     * @return 城市id
     */
    private static String cityCode(String cityName) {
        String httpUrl = "http://apis.baidu.com/apistore/weatherservice/cityname";
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        httpUrl = httpUrl + "?" + "cityname=" + URLEncoder.encode(cityName);
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("apikey", "7e6e0e720498b82c28cdd811d82e5041");
            conn.connect();
            InputStream is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            JSONObject object = new JSONObject(result);
            if (object.getString("errMsg").equals("success")) {
                JSONObject retData = object.getJSONObject("retData");
                String code = retData.getString("citycode");
                //获取当城市ID后，立即通过ID获取天气

                return code;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取天气信息
     *
     * @param cityname 城市名称
     * @param cityid   城市Id
     * @return
     */
    private static String getWeatherInfo(String cityname, String cityid) {
        String httpUrl = "http://apis.baidu.com/apistore/weatherservice/recentweathers";
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        if (cityid == null) {
            httpUrl = httpUrl + "?" + "cityname=" + URLEncoder.encode(cityname);
        } else {
            httpUrl = httpUrl + "?" + "cityname=" + URLEncoder.encode(cityname) + "&cityid=" + URLEncoder.encode(cityid);
        }
//        httpUrl = httpUrl + "?" + "cityname="+cityname+"&cityid="+cityid;
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("apikey", "7e6e0e720498b82c28cdd811d82e5041");
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decodeUnicode(result);
    }

    /**
     * 将unicode码转为中文
     *
     * @param theString
     * @return
     */
    private static String decodeUnicode(String theString) {
        char aChar;
        int len = theString.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len; ) {
            aChar = theString.charAt(x++);
            if (aChar == '\\') {
                aChar = theString.charAt(x++);
                if (aChar == 'u') {
                    // Read the xxxx
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = theString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed   \\uxxxx   encoding.");
                        }

                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't')
                        aChar = '\t';
                    else if (aChar == 'r')
                        aChar = '\r';
                    else if (aChar == 'n')
                        aChar = '\n';
                    else if (aChar == 'f')
                        aChar = '\f';
                    outBuffer.append(aChar);
                }
            } else
                outBuffer.append(aChar);
        }
        return outBuffer.toString();
    }
}
